﻿'###############################################################################################
'#                                                                                             #
'#                     Portal 2 Map Launcher v1.3 Created by ForgottenCoders.                  #
'#                                                                                             #
'#                           DO NOT REMOVE THIS COPYRIGHT NOTICE.                              #
'#                  PLEASE GIVE CREDIT TO ORIGINAL CREATOR (FORGOTTENCODERS)                   #
'#                     DO NOT REMOVE FORGOTTENCODERS FROM THE SPLASHSCREEN                     #
'#                                                                                             #
'###############################################################################################
'#                                                                                             #
'#                          OFFICIAL V2 WILL BE COMPLETED SOON HOPEFULLY                       #
'#                                                                                             #
'###############################################################################################

Imports Microsoft.Win32

Public Class Home
    Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vkey As Long) As Integer 'used for global keybinds
    'The code below dims arrays and adds the defaul list of stock and dlc maps.
    Dim REGLocation As String, REGLocation1 As String, REGMapLocation As String, REGDLCMAPlocation As String
    Dim ARYOtherMaps As New List(Of String), ARYCustomMPMaps As New List(Of String), ARYCustomSPMaps As New List(Of String)
    Dim ARYAllMaps As New List(Of String)
    Dim mapcmd As String, diar1 As IO.FileInfo()
    Dim hotkey As Boolean
    'list stock sp maps
    Dim ARYStockSPMaps() As String = {
    "sp_a1_intro1.bsp", "sp_a1_intro2.bsp", "sp_a1_intro3.bsp", "sp_a1_intro4.bsp", "sp_a1_intro5.bsp", "sp_a1_intro6.bsp", "sp_a1_intro7.bsp",
    "sp_a1_wakeup.bsp", "sp_a2_bridge_intro.bsp", "sp_a2_bridge_the_gap.bsp", "sp_a2_bts1.bsp", "sp_a2_bts2.bsp", "sp_a2_bts3.bsp", "sp_a2_bts4.bsp", "sp_a2_bts5.bsp", "sp_a2_bts6.bsp", "sp_a2_catapult_intro.bsp", "sp_a2_column_blocker.bsp",
    "sp_a2_core.bsp", "sp_a2_dual_lasers.bsp", "sp_a2_fizzler_intro.bsp", "sp_a2_intro.bsp", "sp_a2_laser_chaining.bsp", "sp_a2_laser_intro.bsp", "sp_a2_laser_over_goo.bsp", "sp_a2_laser_relays.bsp", "sp_a2_laser_stairs.bsp",
    "sp_a2_laser_vs_turret.bsp", "sp_a2_pit_flings.bsp", "sp_a2_pull_the_rug.bsp", "sp_a2_ricochet.bsp", "sp_a2_sphere_peek.bsp", "sp_a2_triple_laser.bsp", "sp_a2_trust_fling.bsp", "sp_a2_turret_blocker.bsp", "sp_a2_turret_intro.bsp",
    "sp_a3_00.bsp", "sp_a3_01.bsp", "sp_a3_03.bsp", "sp_a3_bomb_flings.bsp", "sp_a3_crazy_box.bsp", "sp_a3_end.bsp", "sp_a3_jump_intro.bsp", "sp_a3_portal_intro.bsp", "sp_a3_speed_flings.bsp", "sp_a3_speed_ramp.bsp",
    "sp_a3_transition01.bsp", "sp_a4_finale1.bsp", "sp_a4_finale2.bsp", "sp_a4_finale3.bsp", "sp_a4_finale4.bsp", "sp_a4_intro.bsp", "sp_a4_jump_polarity.bsp", "sp_a4_laser_catapult.bsp", "sp_a4_laser_platform.bsp",
    "sp_a4_speed_tb_catch.bsp", "sp_a4_stop_the_box.bsp", "sp_a4_tb_catch.bsp", "sp_a4_tb_intro.bsp", "sp_a4_tb_polarity.bsp", "sp_a4_tb_trust_drop.bsp", "sp_a4_tb_wall_button.bsp", "sp_a5_credits.bsp"
    }
    'list stop mp maps
    Dim ARYStockMPMaps() As String = {
    "mp_coop_catapult_1.bsp", "mp_coop_catapult_2.bsp", "mp_coop_catapult_wall_intro.bsp", "mp_coop_come_along.bsp", "mp_coop_credits.bsp", "mp_coop_doors.bsp", "mp_coop_fan.bsp",
    "mp_coop_fling_1.bsp", "mp_coop_fling_3.bsp", "mp_coop_fling_crushers.bsp", "mp_coop_infinifling_train.bsp", "mp_coop_laser_2.bsp", "mp_coop_laser_crusher.bsp", "mp_coop_lobby_2.bsp", "mp_coop_multifling_1.bsp", "mp_coop_paint_bridge.bsp",
    "mp_coop_paint_come_along.bsp", "mp_coop_paint_longjump_intro.bsp", "mp_coop_paint_red_racer.bsp", "mp_coop_paint_redirect.bsp", "mp_coop_paint_speed_catch.bsp", "mp_coop_paint_speed_fling.bsp", "mp_coop_paint_walljumps.bsp", "mp_coop_race_2.bsp",
    "mp_coop_rat_maze.bsp", "mp_coop_start.bsp", "mp_coop_tbeam_catch_grind_1.bsp", "mp_coop_tbeam_drill.bsp", "mp_coop_tbeam_end.bsp", "mp_coop_tbeam_laser_1.bsp", "mp_coop_tbeam_maze.bsp", "mp_coop_tbeam_polarity.bsp", "mp_coop_tbeam_polarity2.bsp",
    "mp_coop_tbeam_polarity3.bsp", "mp_coop_tbeam_redirect.bsp", "mp_coop_teambts.bsp", "mp_coop_turret_ball.bsp", "mp_coop_turret_walls.bsp", "mp_coop_wall_2.bsp", "mp_coop_wall_5.bsp", "mp_coop_wall_block.bsp", "mp_coop_wall_intro.bsp"
    }
    'list dlc maps
    Dim ARYDLCMaps() As String = {
    "mp_coop_2paints_1bridge.bsp", "mp_coop_bridge_catch.bsp", "mp_coop_catapult_catch.bsp", "mp_coop_laser_tbeam.bsp",
    "mp_coop_lobby_3.bsp", "mp_coop_paint_conversion.bsp", "mp_coop_paint_crazy_box.bsp", "mp_coop_paint_rat_maze.bsp", "mp_coop_separation_1.bsp", "mp_coop_tripleaxis.bsp"
        }
    'list all other bsp files.
    Dim ARYOtherFiles() As String = {
    "aa1.bsp", "aa1a.bsp", "aa2.bsp", "aa3.bsp", "ab1.bsp", "ab12.bsp", "background1.bsp", "bb1.bsp", "bb2.bsp",
    "borealis1.bsp", "borealis2.bsp", "borealis3.bsp", "borealis4.bsp", "borealis5.bsp", "cc1.bsp", "cc2.bsp", "e1912.bsp"
        }
    'Gets Location of portal2.exe from the registry - HKEY_CLASSES_ROOT\Applications\portal2.exe\shell\open\command
    'gets list of files from portal2/maps folder
    'this code could probally be optimized however i have not attempted to yet

    Private Sub Home_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        About.Close()
        Splash.Close()
        Splash.TMRSplash.Stop()
        REGLocation = My.Computer.Registry.GetValue("HKEY_CLASSES_ROOT\Applications\portal2.exe\shell\open\command", "", Nothing)
        REGLocation1 = REGLocation.Replace("\portal2.exe" + Chr(34) + " " + Chr(34) + "%1" + Chr(34), "")
        REGLocation = REGLocation1.Remove(0, 1)
        REGMapLocation = REGLocation + "\portal2\maps"
        REGDLCMAPlocation = REGLocation + "\portal2_dlc1\maps"
        Dim di As New IO.DirectoryInfo(REGMapLocation)
        diar1 = di.GetFiles("*.bsp")
        Timer1.Start()
    End Sub

    'this is the main bit of code when the button is pressed it does a list of checks in this order
    'check if a map is selected if not then does nothing
    'checks if the selected map exists in maps. soon to check dlc folder aswell
    'if it does exist it then checks if changelevel checkbox is ticked
    'if the checkbox is ticked it runs portal2.exe "-hijack -console -novid +changelevel MAPNAME"
    'else if the checkbox is not ticked but portal 2 is running it does the same as above.
    'if portal 2 is not running and the checkbox is not ticked it loads another form which asks for solo,multiplayer,splitscreen.
    'when the solo,online button is pressed it loads portal2.exe "-hijack -console -novid +map MAPNAME"
    'if the splitscreen button is pressed it loads portal2.exe "-hijack -console -novid +ss_map MAPNAME"
    'if the file does not exist it shows a error msg.
    'finally it minimizes the form.
    'new to v1.1 checks if portal2.exe is already running and if it is forces changelevel rather than map.

    Private Sub BTNLaunch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTNLaunch.Click
        If DDNMaps.SelectedItem = Nothing Then
        ElseIf My.Computer.FileSystem.FileExists(REGMapLocation + "\" + DDNMaps.SelectedItem.ToString) Or My.Computer.FileSystem.FileExists(REGDLCMAPlocation + "\" + DDNMaps.SelectedItem.ToString) Then
            Dim mapname As String = DDNMaps.SelectedItem.ToString.Replace(".bsp", "")
            If DDNMaps.SelectedItem.ToString.Contains("sp_") Then
                Shell(Chr(34) + REGLocation + "\portal2.exe " + Chr(34) + "-hijack -windowed -noborder -console -novid +gameui_hide +map " + mapname)
                Me.WindowState = FormWindowState.Minimized
            ElseIf DDNMaps.SelectedItem.ToString.Contains("mp_coop_") Then
                If IsProcessRunning("portal2") = True Then
                    Shell(Chr(34) + REGLocation + "\portal2.exe " + Chr(34) + "-hijack -windowed -noborder -console -novid +gameui_hide +changelevel " + mapname)
                ElseIf CHKSplitScreen.Checked = True Then
                    Shell(Chr(34) + REGLocation + "\portal2.exe " + Chr(34) + "-hijack -windowed -noborder -console -novid +gameui_hide +ss_map " + mapname)
                Else
                    Shell(Chr(34) + REGLocation + "\portal2.exe " + Chr(34) + "-hijack -windowed -noborder -console -novid +gameui_hide +map " + mapname)
                End If
                Me.WindowState = FormWindowState.Minimized
            End If
        Else
            MsgBox("This file does not exist, did you delete it?", MsgBoxStyle.Exclamation, "Error:")
        End If
    End Sub
    Private Sub CHKDefaultSoloMaps_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CHKDefaultSoloMaps.CheckedChanged
        If CHKDefaultSoloMaps.Checked = True Then
            For Each line In ARYStockSPMaps
                DDNMaps.Items.Add(line)
            Next
        Else
            For Each line In ARYStockSPMaps
                DDNMaps.Items.Remove(line)
            Next
        End If
    End Sub
    Private Sub CHKDefaultMPMaps_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CHKDefaultMPMaps.CheckedChanged
        If CHKDefaultMPMaps.Checked = True Then
            For Each line In ARYStockMPMaps
                DDNMaps.Items.Add(line)
            Next
        Else
            For Each line In ARYStockMPMaps
                DDNMaps.Items.Remove(line)
            Next
        End If
    End Sub
    Private Sub CHKDLCMaps_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CHKDLCMaps.CheckedChanged
        If CHKDLCMaps.Checked = True Then
            For Each line In ARYDLCMaps
                DDNMaps.Items.Add(line)
            Next
        Else
            For Each line In ARYDLCMaps
                DDNMaps.Items.Remove(line)
            Next
        End If
    End Sub

    'this is a bit more complicated than the above 3 subs.
    'it checks if a map in the maps folder begins with sp and if does it adds it to the dropdown and a array
    'it also removes the stock maps from that list if the stock checkbox is not checked.
    'i couldn't find a better way of doing this.

    Private Sub CHKCustomSoloMaps_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CHKCustomSoloMaps.CheckedChanged
        If CHKCustomSoloMaps.Checked = True Then
            For Each file In diar1
                If file.ToString.Contains("sp_") Then
                    DDNMaps.Items.Add(file.ToString)
                    ARYCustomSPMaps.Add(file.ToString)
                Else
                End If
            Next
            If CHKDefaultSoloMaps.Checked = False Then
                For Each line In ARYStockSPMaps
                    DDNMaps.Items.Remove(line.ToString)
                Next
            End If
        Else
            For Each line In ARYCustomSPMaps
                DDNMaps.Items.Remove(line.ToString)
            Next
        End If
    End Sub

    'this is a bit more complicated than the above 3 subs.
    'it checks if a map in the maps folder begins with mp_coop_ and if does it adds it to the dropdown and a array
    'it also removes the stock maps and dlc maps from that list if the stock or dlc checkbox is not checked.
    'i couldn't find a better way of doing this.

    Private Sub CHKCustomMPMaps_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CHKCustomMPMaps.CheckedChanged
        If CHKCustomMPMaps.Checked = True Then
            For Each file In diar1
                If file.ToString.Contains("mp_coop_") Then
                    ARYCustomMPMaps.Add(file.ToString)
                    DDNMaps.Items.Add(file.ToString)
                Else
                End If
            Next
            If CHKDefaultMPMaps.Checked = False Then
                For Each line In ARYStockMPMaps
                    DDNMaps.Items.Remove(line.ToString)
                Next
            End If
            If CHKDLCMaps.Checked = False Then
                For Each line In ARYDLCMaps
                    DDNMaps.Items.Remove(line.ToString)
                Next
            End If
        Else
            For Each line In ARYCustomMPMaps
                DDNMaps.Items.Remove(line.ToString)
            Next
        End If
    End Sub
    Private Sub DDNMaps_MouseClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DDNMaps.MouseClick
        For Each line In ARYOtherFiles
            DDNMaps.Items.Remove(line.ToString)
        Next
        Dim i As Long, j As Long
        With DDNMaps
            For i = 0 To .Items.Count - 1
                For j = .Items.Count To (i + 1) Step -1
                    Try
                        If .Items(j) = .Items(i) Then
                            .Items.Remove(j)
                        End If

                        'i had to catch a exception here as it would keep crashing when selecting a map
                        'even though this only happens on launching exe, if i debug it it works fine.

                    Catch ex As ArgumentOutOfRangeException
                    End Try
                Next
            Next
        End With

    End Sub
    'the public function for checking if process running.

    Public Function IsProcessRunning(ByVal name As String) As Boolean
        For Each clsProcess As Process In Process.GetProcesses()
            If clsProcess.ProcessName.StartsWith(name) Then
                Return True
            End If
        Next
        Return False
    End Function
    'new code as of v1.1 this is used for filtering the maps
    Private Sub TXTFilter_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TXTFilter.TextChanged
        DDNMaps.Items.Clear()
        For Each item In ARYAllMaps
            If item.ToString.Contains(TXTFilter.Text) Then
                DDNMaps.Items.Add(item)
            End If
        Next
    End Sub
    'new to v1.1 clones the maplist to a ary so the filter system works
    Private Sub TXTFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TXTFilter.Click
        For Each item In DDNMaps.Items
            ARYAllMaps.Add(item)
        Next
    End Sub
    'clears the filter.
    Private Sub BTNClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTNClear.Click
        TXTFilter.Clear()
    End Sub
    'constantly runs a timer to check when f2 is pressed.
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        hotkey = GetAsyncKeyState(Keys.F2) 'keys.f2 can be changed to any other key to change hotkey.
        If hotkey = True Then
            Shell(Chr(34) + REGLocation + "\portal2.exe " + Chr(34) + "-hijack +hideconsole +gameui_activate")
            Shell(Chr(34) + REGLocation + "\portal2.exe " + Chr(34) + "-hijack +hideconsole")
            Me.Focus()
            Me.BringToFront()
            Me.WindowState = FormWindowState.Normal
        End If
    End Sub
    'infinished options menu.
    Private Sub OptionsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OptionsToolStripMenuItem.Click
        MsgBox("coming soon")
    End Sub
    'closes the program
    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        Me.Close()
    End Sub
    'shows the about box
    Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        About.Show()
    End Sub
    'taskkills portal2.exe
    Private Sub ExitWithPortal2ToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitWithPortal2ToolStripMenuItem.Click
        Shell("taskkill /f /im portal2.exe", vbHide)
    End Sub
    'check if you playing in splitscreen or in network.
    Private Sub CHKSplitScreen_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CHKSplitScreen.CheckedChanged
        If CHKSplitScreen.Checked = True Then
            MessageBox.Show("Portal 2 will now be closed to prevent" + vbNewLine + "the map from being loaded as a Solo/Lan map", "NOTICE")
            Shell("taskkill /f /im portal2.exe", vbHide)
        Else
            MessageBox.Show("Portal 2 will now be closed to prevent" + vbNewLine + "the map from being loaded as a Splitscreen map", "NOTICE")
            Shell("taskkill /f /im portal2.exe", vbHide)
        End If
    End Sub
    'show instructions.
    Private Sub ContentsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ContentsToolStripMenuItem.Click
        Instructions.Show()
    End Sub
End Class